package main

import "fmt"

type RateLimiter struct {
	Count  int
	Bucket chan int
}

func NewRateLimiter(count int) *RateLimiter {
	return &RateLimiter{
		Count:  count,
		Bucket: make(chan int, count),
	}
}

func (r *RateLimiter) GetConn() bool {
	if len(r.Bucket) >= r.Count {
		return false
	}
	r.Bucket <- 1
	return true
}

func (r *RateLimiter) ReleaseConn() {
	<-r.Bucket
}

func main() {
	limiter := NewRateLimiter(10)
	f := make(chan int)
	for i := 0; i < 100; i++ {
		go func() {
			if limiter.GetConn() {
				fmt.Printf("Success \n")
				limiter.ReleaseConn()
			} else {
				fmt.Printf("Fail \n")
			}
			fmt.Printf("Connections is %d \n", len(limiter.Bucket))
			f <- 1
		}()
	}

	for i := 0; i < 100; i++ {
		<-f
	}
}
